package com.yihu.wlyy.web.common.account;

import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import com.yihu.wlyy.entity.SbInfo;
import com.yihu.wlyy.repository.PatientDao;
import com.yihu.wlyy.repository.SbInfoDao;
import com.yihu.wlyy.service.app.family.FamilyService;
import com.yihu.wlyy.util.HttpUtil;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.entity.Token;
import com.yihu.wlyy.service.common.SMSService;
import com.yihu.wlyy.service.common.account.PatientService;
import com.yihu.wlyy.service.common.account.TokenService;
import com.yihu.wlyy.task.PushMsgTask;
import com.yihu.wlyy.util.IdcardValidator;
import com.yihu.wlyy.util.RSAUtils;
import com.yihu.wlyy.web.WeixinBaseController;

/**
 * @author calvin
 */
@Controller
@RequestMapping(value = "/weixin")
//@Api(description = "微信端用户注册")
public class WeinxinController extends WeixinBaseController {

    @Autowired
    private PatientService patientService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private SMSService smsService;
    @Autowired
    private SbInfoDao sbInfoDao;
    @Autowired
    private PatientDao patientDao;
    @Autowired
    private FamilyService familyService;

    /**
     * 患者注册-验证手机号
     *
     * @param phone 登录手机号
     * @return
     */
    @RequestMapping(value = "checkmobile")
    @ResponseBody
    public String checkmobile(String phone) {
        try {
            Patient temp = patientService.findByMobile(phone);
            if (temp != null) {
                JSONObject json = new JSONObject();
                // 设置患者标识
                json.put("code", temp.getCode());
                // 设置身份证号
                json.put("idcard", temp.getIdcard());
                return write(200, "患者信息查询成功！", "data", json);
            }
            return error(1, "该手机号未被注册");
        } catch (Exception e) {
            error(e);
            return error(-1, "手机号验证失败");
        }
    }

    /**
     * 患者注册-验证身份证
     *
     * @param idcard 身份證號
     * @param mobile 登录手机号
     * @return
     */
    @RequestMapping(value = "checkidcard")
    @ResponseBody
    public String checkidcard(String idcard, String mobile) {
        try {
            // 解密身份证号
            idcard = RSAUtils.getInstance(patientService).decryptString(idcard);
            idcard = URLDecoder.decode(idcard, "UTF-8");
            idcard = StringUtils.reverse(idcard);
            Patient temp = patientService.findByIdcard(idcard);
            if (temp != null) {
                JSONObject json = new JSONObject();
                // 设置患者标识
                json.put("code", temp.getCode());
                // 设置手机号码
                json.put("mobile", temp.getMobile());
                // 设置身份证号
                json.put("idcard", temp.getIdcard());
                return write(1, "患者信息查询成功！", "data", json);
            } else {
                Patient temp1 = patientService.findByMobile(mobile);
                if (temp1 != null) {
                    JSONObject json = new JSONObject();
                    // 设置患者标识
                    json.put("code", temp1.getCode());
                    // 设置手机号码
                    json.put("mobile", temp1.getMobile());
                    // 设置身份证号
                    json.put("idcard", temp1.getIdcard());
                    return write(2, "患者信息查询成功！", "data", json);
                }
            }
            return success("该身份证和手机号未被注册");
        } catch (Exception e) {
            error(e);
            return error(-1, "身份证验证失败");
        }
    }

    /**
     * 注册信息验证
     *
     * @param name 姓名
     * @param idcard 身份证号
     * @param ssc 社保卡号
     * @param mobile 手机号
     * @return
     */
    @RequestMapping(value = "/check_regist_info")
    @ResponseBody
    public String checkRegistInfo(String name,String idcard,String ssc,String mobile){
        try{
            if (StringUtils.isEmpty(name)) {
                return error(-1, "姓名不允许为空");
            }
            if (StringUtils.isEmpty(idcard)) {
                return error(-1, "身份证号不允许为空");
            }
            if (StringUtils.isEmpty(ssc)) {
                return error(-1, "社保卡号不允许为空");
            }
            if (StringUtils.isEmpty(mobile)) {
                return error(-1, "手机号不允许为空");
            }
            if (patientService.findByMobile(mobile) != null) {
                return error(-1, "该手机号已被注册");
            }
            // 解密身份证号
            idcard = RSAUtils.getInstance(patientService).decryptString(idcard);
            idcard = URLDecoder.decode(idcard, "UTF-8");
            idcard = StringUtils.reverse(idcard);
            // 校验身份证号
            IdcardValidator validator = new IdcardValidator();
            if (validator.isValidatedAllIdcard(idcard)) {
                if (idcard.length() == 15) {
                    idcard = validator.convertIdcarBy15bit(idcard);
                    if (StringUtils.isEmpty(idcard)) {
                        return error(-1, "请输入正确的身份证号");
                    }
                }
            } else {
                return error(-1, "请输入正确的身份证号");
            }

            SbInfo sbInfo = sbInfoDao.findBySfzh18Max(idcard);

            if(sbInfo != null){
                if(name.compareTo(sbInfo.getXming0() == null ? "" : sbInfo.getXming0()) != 0){
                    return error(-1,"身份证号与姓名不一致，请检查后重新输入");
                }
                if(ssc.compareTo(sbInfo.getCardno() == null ? "" : sbInfo.getCardno()) != 0&&ssc.compareTo(sbInfo.getCard16() == null ? "" : sbInfo.getCard16()) != 0){
                    return error(-1,"身份证号与医保卡号不一致，请检查后重新输入");
                }
            }else{
                return error(-1,"对不起，暂不支持16年6月份之后办理的医保卡注册");
            }

            Patient patient = patientDao.findByIdcard(idcard);

            if(patient != null){
                if (!StringUtils.isEmpty(patient.getMobile())) {
                    return error(-1, "该身份证已被注册");
                }
            }

            return write(200,"验证成功");
        }catch(Exception e){
            e.printStackTrace();
            return error(-1,"验证失败");
        }
    }

    /**
     * 患者注册
     *
     * @param idcard   身份證號
     * @param mobile   登录手机号
     * @param captcha  手机验证码
     * @return
     */
    @RequestMapping(value = "regist")
    @ResponseBody
    public String regist(String name, String idcard, String ssc, String mobile, String captcha, String openid) {
        try {
            if (StringUtils.isEmpty(name)) {
                return error(-1, "姓名不允许为空！");
            }
            if (StringUtils.isEmpty(idcard)) {
                return error(-1, "身份证号不允许为空！");
            }
			if (StringUtils.isEmpty(ssc)) {
				return error(-1, "社保卡号不允许为空！");
			}
            if (StringUtils.isEmpty(mobile)) {
                return error(-1, "手机号不允许为空！");
            }
            if (patientService.findByMobile(mobile) != null) {
                return error(-1, "该手机号已被注册！");
            }
            // 对验证码进行校验
            int res = smsService.check(mobile, 1, captcha);
            switch (res) {
                case -2:
                    return error(-1, "验证码已过期！");
                case -1:
                    return error(-1, "请输入正确的验证码！");
                case 0:
                    return error(-1, "验证码无效！");
            }
            // 未绑定openid，查询是否绑定其他帐号
//			if (patientService.countByOpenid(openid) > 0) {
//				return error(-1, "该微信号已绑定其他手机号！");
//			}
            // 解密身份证号
            idcard = RSAUtils.getInstance(patientService).decryptString(idcard);
            idcard = URLDecoder.decode(idcard, "UTF-8");
            idcard = StringUtils.reverse(idcard);
            // 校验身份证号
            IdcardValidator validator = new IdcardValidator();
            if (validator.isValidatedAllIdcard(idcard)) {
                if (idcard.length() == 15) {
                    idcard = validator.convertIdcarBy15bit(idcard);
                    if (StringUtils.isEmpty(idcard)) {
                        return error(-1, "请输入正确的身份证号！");
                    }
                }
            } else {
                return error(-1, "请输入正确的身份证号！");
            }

            SbInfo sbInfo = sbInfoDao.findBySfzh18Max(idcard);

            if(sbInfo != null){
                if(name.compareTo(sbInfo.getXming0() == null ? "" : sbInfo.getXming0()) != 0){
                    return error(-1,"身份证号与姓名不一致<br/>请检查后重新输入");
                }
                if(ssc.compareTo(sbInfo.getCardno() == null ? "" : sbInfo.getCardno()) != 0){
                    if(ssc.compareTo(sbInfo.getCard16() == null ? "" : sbInfo.getCard16()) != 0){
                         return error(-1,"身份证号与医保卡号不一致，请检查后重新输入");
                    }else{
                        ssc=sbInfo.getCardno();//统一只存英文字母开头的医保卡
                    }
                }
            }else{
                return error(-1,"对不起，暂不支持16年6月份之后办理的医保卡注册");
            }

            Patient patient = patientDao.findByIdcard(idcard);

            if(patient == null){
                patient = new Patient();
            }else{
                if (!StringUtils.isEmpty(patient.getMobile())) {
                    return error(-1, "该身份证已被注册！");
                }
            }
            patient.setName(name);
            patient.setIdcard(idcard);
            patient.setMobile(mobile);
			patient.setSsc(ssc);
            patient.setOpenid(openid);
            JSONObject json = patientService.register(patient, openid, 3);
            if (json != null) {
                // 注册成功
                return write(200, "注册成功！", "data", json);
            } else {
                // 注册失败
                return error(-1, "注册失败！");
            }
        } catch (Exception e) {
            error(e);
            return error(-1, "注册失败！");
        }
    }

    /**
     * 患者微信登录接口
     *
     * @param idcard   身份證号
     * @param password 登录密码
     * @return
     */
    @RequestMapping(value = "login")
    @ResponseBody
    public String login(String mobile, String captcha, String openid) {
        try {
            // 对验证码进行校验
            int res = smsService.check(mobile, 4, captcha);
            switch (res) {
                case -2:
                    return error(-1, "验证码已过期！");
                case -1:
                    return error(-1, "请输入正确的验证码！");
                case 0:
                    return error(-1, "验证码无效！");
            }
            Patient patient = patientService.findByMobile(mobile);
            if (patient == null) {
                return error(-1, "该手机号暂未注册帐号，请确认后重新输入！");
            } else if (patient.getStatus() == 0) {
                return error(-1, "该手机号已被禁止使用！");
            } else if (patient.getStatus() == 2) {
                return error(-1, "该帐号正在审核中，请确认审核通过后再登录，“如有疑问，拨打400-6677-400转2人工客服”");
            } else if (StringUtils.isEmpty(openid)) {
                return error(-1, "无效的OpenID！");
            }
//			else if (StringUtils.isNotEmpty(patient.getOpenid()) && !StringUtils.equals(patient.getOpenid(), openid)) {
//				return error(-1, "该微信号已绑定其他手机号！");
//			}else if (StringUtils.isEmpty(patient.getOpenid())) {
//				// 未绑定openid，查询是否绑定其他帐号
//				if (patientService.countByOpenid(openid) > 0) {
//					return error(-1, "该微信号已绑定其他手机号！");
//				} else {
//					// 绑定用户手机号和openid
//					patient.setOpenid(openid);
//					patientService.updatePatient(patient);
//				}
//			}

            // 绑定用户手机号和openid
            if (!StringUtils.equals(patient.getOpenid(), openid)) {
                patient.setOpenid(openid);
                patientService.updatePatient(patient);
            }

            // 用户校验通过，生成token
            Token token = tokenService.newTxToken(patient.getCode(), openid);
            Map<Object, Object> map = new HashMap<Object, Object>();
            map.put("id", patient.getId());
            map.put("uid", patient.getCode());
            map.put("name", patient.getName());
            map.put("token", token.getToken());
            map.put("photo", patient.getPhoto());
            if(StringUtils.isNoneEmpty(openid)){
                //发送微信模板
                familyService.sendWXMessage(patient);
            }
            return write(200, "登录成功", "data", map);
        } catch (Exception e) {
            error(e);
            return error(-1, "系统异常，登录失败");
        }
    }

    /**
     * 获取签名signature
     *
     * @param pageUrl需要签名的页面全地址（？后的也需要除了#后的不需要）
     * @return
     */
    @RequestMapping(value = "getSign")
    @ResponseBody
    public String getSign(String pageUrl) {
        try {
            String ticket = getJsapi_ticketByToken();
            if (ticket != null) {
                String noncestr = UUID.randomUUID().toString();
                long timestamp = System.currentTimeMillis() / 1000;
                String url = pageUrl;
                String str = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
                // sha1加密
                String signature = SHA1(str);

                Map<Object, Object> map = new HashMap<Object, Object>();
                map.put("noncestr", noncestr);
                map.put("timestamp", timestamp);
                map.put("signature", signature);
                return write(200, "获取签名成功", "data", map);
            } else
                return error(-1, "获取签名失败");

        } catch (Exception e) {
            error(e);
        }
        return error(-1, "获取签名失败");
    }

    /**
     * 发送微信签约成功的消息
     *
     * @param code患者编号
     * @return
     */
    @RequestMapping(value = "sendSign")
    @ResponseBody
    public String sendSignSucess(String code) {
        try {
            Patient patient = patientService.findByCode(code);
            JSONObject json = new JSONObject();
            json.put("first", "开始");
            json.put("remark", "指导备注");
            json.put("date", "2016-06-08");
            json.put("doctorName", "徐小鹏");
            json.put("orgName", "厦门第一医院");
            PushMsgTask.getInstance().putWxMsg(getAccessToken(), 5, patient.getOpenid(), patient.getName(), json);
            return write(200, "发送成功");
        } catch (Exception e) {
            error(e);
            return error(-1, "发送失败");
        }
    }

    /**
     * 获取微信用户身份
     * @param code
     * @return
     */
    // @RequestMapping(value = "identity")
    // @ResponseBody
    // public String identity(String code) {
    // try {
    // String openid = getOpenid();
    // if(StringUtils.isEmpty(openid)){
    // openid = getOpenidByCode(code);
    // }
    // if (StringUtils.isEmpty(openid)) {
    // return error(-1, "获取openid异常！");
    // }
    // JSONObject userAgent = new JSONObject();
    // Patient patient = patientService.findByOpenid(openid);
    // long id = 0;
    // String uid = "";
    // String name = "";
    // String photo = "";
    // String tokenStr = "";
    // if (patient != null) {
    // id = patient.getId();
    // uid = patient.getCode();
    // name = patient.getName();
    // photo = patient.getPhoto();
    // // 查询token
    // Token token = SystemData.wxPatientTokens.get(patient.getCode());
    // if (token == null) {
    // // 从数据库加载
    // token = tokenService.findWxToken(patient.getCode());
    // }
    // if (token == null) {
    // // 生成新的token
    // token = tokenService.newTxToken(patient.getCode(), openid);
    // }
    // tokenStr = token.getToken();
    // }
    // userAgent.put("id", id);
    // userAgent.put("uid", uid);
    // userAgent.put("openid", openid);
    // userAgent.put("name", name);
    // userAgent.put("photo", photo);
    // userAgent.put("token", tokenStr);
    // return write(200, "获取身份信息成功！", "data", userAgent);
    // } catch (Exception e) {
    // error(e);
    // return error(-1, "获取身份信息失败！");
    // }
    // }

    /**
     * 获取微信openid
     *
     * @param code
     * @return
     */
    @RequestMapping(value = "getOpenidByCode")
    @ResponseBody
    public String getOpenidByCode(String code) {
        try {
            String openid = super.getOpenidByCode(code);
            if (!StringUtils.isEmpty(openid)) {
                return write(200, "获取openid成功！", "openid", openid);
            } else {
                return error(-1, "获取openid失败！");
            }
        } catch (Exception e) {
            error(e);
            return error(-1, "获取openid失败！");
        }
    }

    /**
     * 判断是否关注
     *
     * @param openid
     * @return
     */
    @RequestMapping(value = "/is_subscribe")
    @ResponseBody
    public String getIsSubscribe(String openid){
        try{
            String userInfo_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+ getAccessToken()+ "&openid=" + openid + "&lang=zh_CN";
            String params = "";
            String result = HttpUtil.sendGet(userInfo_url, params);
            JSONObject json = new JSONObject(result);
            if (json.has("subscribe")) {
                return write(200,"查询成功","subsribe",json.get("subscribe").toString());
            } else {
                return error(-1,json.getString("errmsg"));
            }
        }catch (Exception e){
            e.printStackTrace();
            return error(-1,"查询失败");
        }
    }
}
